package edu.upb.acs.jobsmaps.database.mysql;

import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import edu.upb.acs.jobsmaps.database.HttpRequestHandler;
import edu.upb.acs.jobsmaps.database.table.CompanyTableInfo;
import edu.upb.acs.jobsmaps.database.table.JobTableInfo;
import edu.upb.acs.jobsmaps.entity.Company;
import edu.upb.acs.jobsmaps.entity.Job;
import edu.upb.acs.jobsmaps.entity.User;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * Created by dani on 5/24/2014.
 */
public class ExternalDatabaseHelper {

	//TODO insert your IP here
	private static final String IP = "192.168.1.111";
	private static final String PORT = "8080";

	private static final String URL_GET_COMPANIES = "http://" + IP + ":" + PORT + "/jobs/getCompanies.php";
	private static final String URL_SEARCH_COMPANIES = "http://" + IP + ":" + PORT + "/jobs/searchCompanies.php";
	private static final String URL_SEARCH_JOBS = "http://" + IP + ":" + PORT + "/jobs/searchJobs.php";

	private static final String URL_ADD_COMPANY = "http://" + IP + ":" + PORT + "/jobs/addCompany.php";
	private static final String URL_ADD_JOB = "http://" + IP + ":" + PORT + "/jobs/addJob.php";

	private static final String URL_GET_JOB_AFTER_ID = "http://" + IP + ":" + PORT + "/jobs/getJobAfterId.php";
	private static final String URL_GET_COMPANY_AFTER_ID = "http://" + IP + ":" + PORT + "/jobs/getCompanyAfterId.php";

	private static final String URL_ADD_USER = "http://" + IP + ":" + PORT + "/jobs/addUser.php";
	private static final String URL_GET_USER_AFTER_EMAIL = "http://" + IP + ":" + PORT + "/jobs/getUserAfterEmail.php";

	private static final String URL_ADD_RATING = "http://" + IP + ":" + PORT + "/jobs/addRating.php";

	private static final String TAG = ExternalDatabaseHelper.class.getName();

	public static Collection<Company> getCompanies() {
		Log.d(ExternalDatabaseHelper.class.getName(), "Get companies");
		String responseBody = HttpRequestHandler.makeHttpRequest(URL_GET_COMPANIES, "GET", null);

		Collection<Company> companies = getCompaniesFromResponse(responseBody);

		Log.d(TAG, "Return " + companies.size() + " companies");

		return companies;
	}


	public static Collection<Company> searchCompanies(String searchCriteria, String searchWord) {
		List<NameValuePair> params = new ArrayList<>();
		params.add(new BasicNameValuePair("searchWord", searchWord));

		//convert from search word to search field
		String searchField = null;
		if (searchCriteria.equals("Name")) {
			searchField = CompanyTableInfo.FIELD_NAME;
		} else if (searchCriteria.equals("Description")) {
			searchField = CompanyTableInfo.FIELD_DESCRIPTION;
		} else if (searchCriteria.equals("Profile")) {
			searchField = CompanyTableInfo.FIELD_PROFILE;
		} else if (searchCriteria.equals("Any")) {
			//do nothing
		}else {
			Log.e(TAG, "Received unsupported value for search criteria = " + searchCriteria);
		}
		if (null != searchField) {
			params.add(new BasicNameValuePair("searchField", searchField));
		}
		Log.d(TAG, "Search companies with params = " + params);
		String responseBody = HttpRequestHandler.makeHttpRequest(URL_SEARCH_COMPANIES, "GET", params);

		Collection<Company> companies = getCompaniesFromResponse(responseBody);

		Log.d(TAG, "Return " + companies.size() + " companies");

		return companies;
	}

	public static Collection<Job> searchJobs(String searchCriteria, String searchWord, String searchProfile) {
		List<NameValuePair> params = new ArrayList<>();
		params.add(new BasicNameValuePair("searchWord", searchWord));
		if (!searchProfile.equals("Any")){
			params.add(new BasicNameValuePair("searchProfile", searchProfile));
		}

		String searchField = null;

		if (searchCriteria.equals("Name")) {
			searchField = JobTableInfo.FIELD_NAME;
		} else if (searchCriteria.equals("Description")) {
			searchField = JobTableInfo.FIELD_DESCRIPTION;
		} else if (searchCriteria.equals("Salary")) {
			searchField = JobTableInfo.FIELD_SALARY;
		}else if (searchCriteria.equals("Company")) {
			searchField = "companyName";
		} else if (searchCriteria.equals("Any")) {
			//do nothing
		} else {
			Log.d(TAG, "received unsupported value for search criteria = " + searchCriteria);
		}
		if (null != searchField) {
			params.add(new BasicNameValuePair("searchField", searchField));
		}
		Log.d(TAG, "Search jobs with params = " + params);
		String responseBody = HttpRequestHandler.makeHttpRequest(URL_SEARCH_JOBS, "GET", params);

		Collection<Job> jobs = getJobsFromResponse(responseBody);

		Log.d(TAG, "Return " + jobs.size() + " jobs");

		return jobs;
	}

	public static Integer addCompany(Company company) {
		List<NameValuePair> params = new ArrayList<>();
		params.add(new BasicNameValuePair("name", company.getName()));
		params.add(new BasicNameValuePair("description", company.getDescription()));
		params.add(new BasicNameValuePair("latitude", company.getLatitude().toString()));
		params.add(new BasicNameValuePair("longitude", company.getLongitude().toString()));
		params.add(new BasicNameValuePair("profile", company.getProfile()));
		params.add(new BasicNameValuePair("companyUrl", company.getCompanyUrl()));

		String responseBody = HttpRequestHandler.makeHttpRequest(URL_ADD_COMPANY, "POST", params);


		Integer companyId = Integer.valueOf(responseBody);
		Log.d(TAG, "Company was added with id = " + companyId);
		return companyId;
	}

	public static Integer addJob(Job job) {
		List<NameValuePair> params = new ArrayList<>();
		params.add(new BasicNameValuePair("name", job.getName()));
		params.add(new BasicNameValuePair("description", job.getDescription()));
		params.add(new BasicNameValuePair("latitude", job.getLatitude().toString()));
		params.add(new BasicNameValuePair("longitude", job.getLongitude().toString()));
		params.add(new BasicNameValuePair("companyId", job.getCompanyId()));
		params.add(new BasicNameValuePair("salary", job.getSalary().toString()));
		params.add(new BasicNameValuePair("active", job.getActive().toString()));

		if (null != job.getJobUrl()) {
			params.add(new BasicNameValuePair("jobUrl", job.getJobUrl()));
		}
		if (null != job.getPostedDate()) {
			SimpleDateFormat dt1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String date = dt1.format(job.getPostedDate());
			Log.d(TAG, "** Date = " + date);
			params.add(new BasicNameValuePair("postedDate", date));
		}

		String responseBody = HttpRequestHandler.makeHttpRequest(URL_ADD_JOB, "POST", params);

		Integer jobId = Integer.valueOf(responseBody);
		Log.d(TAG, "Job was added with id = " + jobId);
		return jobId;
	}

	public static Job getJobAfterId(String id) {
		List<NameValuePair> params = new ArrayList<>();
		params.add(new BasicNameValuePair("id", id));

		String responseBody = HttpRequestHandler.makeHttpRequest(URL_GET_JOB_AFTER_ID, "GET", params);
		if (responseBody.equals("[]")){
			return null;
		}

		Job job = getJobFromResponse(responseBody);
		return job;
	}

	public static Company getCompanyAfterId(String id) {
		List<NameValuePair> params = new ArrayList<>();
		params.add(new BasicNameValuePair("id", id));

		String responseBody = HttpRequestHandler.makeHttpRequest(URL_GET_COMPANY_AFTER_ID, "GET", params);
		if (responseBody.equals("[]")){
			return null;
		}

		return getCompanyFromResponse(responseBody);
	}

	public static Integer addUser(User user) {
		List<NameValuePair> params = new ArrayList<>();
		params.add(new BasicNameValuePair("username", user.getUsername()));
		params.add(new BasicNameValuePair("firstName", user.getFirstName()));
		params.add(new BasicNameValuePair("lastName", user.getLastName()));
		params.add(new BasicNameValuePair("email", user.getEmail()));
		params.add(new BasicNameValuePair("googleId", user.getGoogleId()));

		String responseBody = HttpRequestHandler.makeHttpRequest(URL_ADD_USER, "POST", params);


		Integer userId = Integer.valueOf(responseBody);
		Log.d(TAG, "User was added with id = " + userId);
		return userId;
	}

	public static User getUserAfterEmail(String email) {
		List<NameValuePair> params = new ArrayList<>();
		params.add(new BasicNameValuePair("email", email));

		String responseBody = HttpRequestHandler.makeHttpRequest(URL_GET_USER_AFTER_EMAIL, "GET", params);

		if (responseBody.equals("[]")){
			return null;
		}
		return getUserFromResponse(responseBody);
	}

	public static Integer addRating(String valueRating, String companyId) {
		List<NameValuePair> params = new ArrayList<>();
		params.add(new BasicNameValuePair("value",valueRating));
		params.add(new BasicNameValuePair("companyId", companyId));

		String responseBody = HttpRequestHandler.makeHttpRequest(URL_ADD_RATING, "POST", params);

		Log.d(TAG, responseBody);
//		Integer ratingID = Integer.valueOf(responseBody);
//		Log.d(TAG, "Rating was added with id = " + ratingID);
//		return ratingID;
		return 1;
	}

	private static Collection<Company> getCompaniesFromResponse(String responseBody) {
		Gson gson = new Gson();
		Type listType = new TypeToken<Collection<Company>>() {}.getType();
		return gson.fromJson(responseBody, listType);
	}


	private static Company getCompanyFromResponse(String responseBody) {
		Gson gson = new Gson();
		Type listType = new TypeToken<Company>() {}.getType();
		return gson.fromJson(responseBody, listType);
	}

	private static Collection<Job> getJobsFromResponse(String responseBody) {
		Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
		Type listType = new TypeToken<Collection<Job>>() {}.getType();
		return gson.fromJson(responseBody, listType);
	}

	private static Job getJobFromResponse(String responseBody) {
		Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
		Type listType = new TypeToken<Job>() {}.getType();
		return gson.fromJson(responseBody, listType);
	}

	private static User getUserFromResponse(String responseBody) {
		Gson gson = new Gson();
		Type listType = new TypeToken<User>() {}.getType();
		return gson.fromJson(responseBody, listType);
	}


}